package com.fjwt.gz.task.activity;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjwt.gz.db.entity.StatActe017NumEntity;
import com.fjwt.gz.db.entity.StatActe017RecordEntity;
import com.fjwt.gz.service.impl.FansAwardService;
import com.fjwt.gz.service.impl.StatActe017RecordService;
import com.fjwt.gz.service.mapper.StatActe017NumMapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * ACTE017越减越便宜活动--用户参与记录明细
 */
@Component
@Slf4j
public class ACTE017NumTask {

    @Autowired
    private FansAwardService fansAwardService;
    @Autowired
    private StatActe017RecordService statActe017RecordService;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    private static final int QUERY_PAGE_SIZE = 10000; //每次查询数量

    private static final int SAVE_BATCH_SIZE = 2000; //每次查询数量

//    @Scheduled(cron = "0 1 * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void fansRecord() {
        log.info("开始进入：ACTE017越减越便宜活动--入链渠道机构统计 的定时任务，开始时间:{}", DateUtil.now());
        int currentPageIndex = 1; // 当前页数
        while (true) {
            try {
                IPage<StatActe017NumEntity> numEntityIPage =
                        statActe017RecordService.getStatActe017Num(new Page(currentPageIndex, QUERY_PAGE_SIZE));
                log.info("查询页数：{}，size:{}，结果list：{}", currentPageIndex, QUERY_PAGE_SIZE, JSONUtil.toJsonStr(numEntityIPage));

                // 本次查询结果为空 跳出当前循环
                if (ObjectUtil.isEmpty(numEntityIPage.getRecords())) {
                    break;
                }

                // 赋值agentInfo 相关的信息
                setAgentInfo(numEntityIPage.getRecords());

                // 赋值激活数量
                setActiveNum(numEntityIPage.getRecords());

                // 新增
                addBatch(numEntityIPage.getRecords());

                currentPageIndex++;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        log.info("结束：ACTE017越减越便宜活动--入链渠道机构统计 的定时任务，结束时间:{}", DateUtil.now());
    }

    /**
     * 批量新增
     * @param records
     */
    private void addBatch(List<StatActe017NumEntity> records){
        // 使用原生 批处理的形式进行插入
        try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
            // 分批插入数据
            List<List<StatActe017NumEntity>> partition =
                    Lists.partition(records, SAVE_BATCH_SIZE);

            StatActe017NumMapper statActe017NumMapper = sqlSession.getMapper(StatActe017NumMapper.class);
            partition.parallelStream()
                    .forEach(statActe017NumMapper::insert);
            sqlSession.commit();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 设置激活数量
     *
     * @param records
     */
    private void setActiveNum(List<StatActe017NumEntity> records) {
        Map<String, StatActe017NumEntity> appAndAgentTmpMap = records.parallelStream()
                .collect(Collectors.toMap(item -> item.getLiteAppId() + "_" + item.getActivityId() + "_" + item.getAgentNo(), Function.identity()));

        List<String> liteAppIdList =
                records.parallelStream()
                        .map(StatActe017NumEntity::getLiteAppId)
                        .distinct()
                        .toList();

        List<Long> activityIdList = records.parallelStream()
                .map(StatActe017NumEntity::getActivityId)
                .distinct()
                .toList();

        List<String> agentNoList =
                records.parallelStream()
                        .map(StatActe017NumEntity::getAgentNo)
                        .distinct()
                        .toList();

        List<Map<String, Object>> activateCount = fansAwardService.getActivateCount(liteAppIdList, activityIdList, agentNoList);

        activateCount.parallelStream()
                .forEach(item -> {
                    if (appAndAgentTmpMap.containsKey(String.valueOf(item.get("ws_keys")))){
                        StatActe017NumEntity entityTmp = appAndAgentTmpMap.get(String.valueOf(item.get("ws_keys")));
                        switch (String.valueOf(item.get("remark"))){
                            case "B1": entityTmp.setTotalB1ActiveNum(Integer.valueOf(String.valueOf(item.get("num"))));
                            case "B3": entityTmp.setTotalB3ActiveNum(Integer.valueOf(String.valueOf(item.get("num"))));
                            case "C": entityTmp.setTotalCActiveNum(Integer.valueOf(String.valueOf(item.get("num"))));
                            case "D": entityTmp.setTotalDActiveNum(Integer.valueOf(String.valueOf(item.get("num"))));
                        }
                    }
                });

    }

    /**
     * 赋值agent 相关信息
     *
     * @param list
     */
    private void setAgentInfo(List<StatActe017NumEntity> list) {
        Map<String, List<StatActe017NumEntity>> agentNoMap =
                list.parallelStream()
                        .filter(item -> ObjectUtil.isNotEmpty(item.getAgentNo()))
                        .collect(Collectors.groupingBy(StatActe017NumEntity::getAgentNo));

        QueryWrapper<StatActe017RecordEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("SUBSTRING_INDEX(first_channel_code,'_',1)", agentNoMap.keySet());
        queryWrapper.eq("stat_date", DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -1)));

        Map<String, List<StatActe017RecordEntity>> recordEntityMap =
                this.statActe017RecordService.list(queryWrapper).parallelStream()
                        .collect(Collectors.groupingBy(item -> item.getFirstChannelCode().split("-")[0]));

        agentNoMap.forEach((k, v) -> {
            StatActe017RecordEntity recordEntity = recordEntityMap.get(k).get(0);
            v.parallelStream().forEach(item -> {
                item.setAgentNo1(recordEntity.getChannelAgentNo1());
                item.setAgentName1(recordEntity.getChannelAgentName1());
                item.setAgentNo2(recordEntity.getChannelAgentNo2());
                item.setAgentName2(recordEntity.getChannelAgentName2());
                item.setAgentNo3(recordEntity.getChannelAgentNo3());
                item.setAgentName3(recordEntity.getChannelAgentName3());
                item.setAgentNo4(recordEntity.getChannelAgentNo4());
                item.setAgentName4(recordEntity.getChannelAgentName4());
            });
        });
    }

}
